package cn.tedu.charging.order.quartz;


import cn.tedu.charging.order.dao.repository.OrderRepository;
import cn.tedu.charging.order.pojo.po.ChargingOrderFilePO;
import cn.tedu.charging.order.pojo.po.ChargingOrderSuccessPO;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.Date;
import java.util.UUID;

@Slf4j
public class DeviceCheckJob implements Job {

    /**
     * 必须有一个无参数的构造器
     *  如果没有， 在初始化 new DeviceCheckJob 调用 Class newInstance 实例化，通过无参的构造器实例化对象
     *  getConstructor0() 获取无参构造器
     *  public DeviceCheckJob(String orderNo, Integer gunId) 覆盖 默认的无参构造器
     *  找不到方法 抛异常 NoSuchMethodException  找不到构造器，创建不了 DeviceCheckJob对象
     */
    public DeviceCheckJob() {}

    public DeviceCheckJob(String orderNo, Integer gunId) throws SchedulerException {
        log.debug("添加设备的自检定时任务，订单号:{},枪Id:{}",orderNo,gunId);

        // 创建调度器工厂
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        // 获取调度器
        Scheduler scheduler = schedulerFactory.getScheduler();
        // 创建一个任务
        JobDetail jobDetail = JobBuilder.newJob(DeviceCheckJob.class)
                // 定义任务的名称和组 （分类）
                .withIdentity("device-check-job"+ UUID.randomUUID(),
                        "device-check-job-group")
                .usingJobData("orderNo",orderNo)
                .usingJobData("gunId",gunId)
                .build();
        // 获取时间 为触发器做准备
        long now = System.currentTimeMillis();
        // 任务的执行时间为当前时间的一分钟以后
        long deviceCheckTime = now+60*1000;
        // 转换格式为时间格式
        Date triggerTime = new Date(deviceCheckTime);
        // 创建触发器
        Trigger trigger = TriggerBuilder.newTrigger()
                .startAt(triggerTime)
                .build();
        // 将任务和触发器添加到调度器中 绑定
        scheduler.scheduleJob(jobDetail,trigger);
        // 启动
        scheduler.start();
        log.debug("设备自检任务添加成功");

    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // 获取订单数据 订单编号 和枪id
        log.debug("设备自检任务开始执行");
        String orderNo = jobExecutionContext.getJobDetail().getJobDataMap().getString("orderNo");
        Integer gunId = jobExecutionContext.getJobDetail().getJobDataMap().getInt("gunId");
        log.debug("设备自检任务执行，订单号:{},枪Id:{}",orderNo,gunId);

        // 执行具体的业务
        OrderRepository orderRepository = SpringContextUtils.getBean(OrderRepository.class);
        // 查询成功订单
        log.debug("查询成功订单:订单号:{}",orderNo);
        ChargingOrderSuccessPO chargingOrderSuccessPO = orderRepository.getOrderSuccess(orderNo);
        log.debug("查询成功订单,订单号:{},结果:{}",orderNo,chargingOrderSuccessPO);
        if(chargingOrderSuccessPO==null){
            // 查询订单失败记录
            log.debug("查询失败订单:订单号:{}",orderNo);
            ChargingOrderFilePO chargingOrderFilePO = orderRepository.getOrderFile(orderNo);
            log.debug("查询失败订单,订单号:{},结果:{}",orderNo,chargingOrderFilePO);
            if(chargingOrderFilePO==null){
                // 插入失败订单记录
                chargingOrderFilePO = new ChargingOrderFilePO();
                chargingOrderFilePO.setBillId(orderNo);
                chargingOrderFilePO.setFailDesc("设备自检失败-设备无响应");
                log.debug("保存失败订单记录:{}",chargingOrderFilePO);
                Integer row = orderRepository.insertOrderFile(chargingOrderFilePO);
                log.debug("保存失败订单记录，订单记录:{},受影响行数:{}",chargingOrderFilePO,row);
                log.debug("设备发送的消息，是充电失败的消息,通知用户和维修人员 ");
                log.debug("给用户发送优惠券 表示歉意 给用户心灵上的安慰");
            }
        }

    }
}
